package com.thread.exector;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

public class JHThreadPoolExecutor extends ThreadPoolExecutor {

	/** 记录每个线程执行任务开始时间*/
	private ThreadLocal<Long> start = new ThreadLocal<Long>();

	/** 记录所有任务完成使用的时间*/
	private AtomicLong totals = new AtomicLong();

	/** 记录线程池完成的任务数*/
	private AtomicInteger tasks = new AtomicInteger();

	public JHThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
			BlockingQueue<Runnable> workQueue) {
		super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
	}

	public JHThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
			BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) {
		super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
	}

	public JHThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
			BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
		super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
	}

	public JHThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
			BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
		super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
	}

	/**
	 * 每个线程在调用run方法之前调用该方法
	 */
	protected void beforeExecute(Thread t, Runnable r) {
		super.beforeExecute(t, r);
		start.set(System.currentTimeMillis());
	}

	/** 每个线程在执行完run方法后调用该方法*/
	protected void afterExecute(Runnable r, Throwable t) {
		super.afterExecute(r, t);
		tasks.incrementAndGet();
		totals.addAndGet(System.currentTimeMillis() - start.get());
	}

	@Override
	protected void terminated() {
		super.terminated();
		System.out.println("[THREADPOOL]完成" + tasks.get() + "个任务,平均耗时:" + totals.get() / tasks.get() + ".ms");
	}

	public static void main(String[] args) {
		BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>();
		JHThreadPoolExecutor executor = new JHThreadPoolExecutor(3, 5, 5, TimeUnit.MINUTES, queue);
		for (int i = 0; i < 5; ++i) {
			executor.submit(new Task());
		}
		executor.shutdown();
	}
}

class Task implements Runnable {

	@Override
	public void run() {
		try {
			TimeUnit.SECONDS.sleep(5);
		} catch (Exception e) {
			System.err.println(e.getMessage());
		}
	}

}
